package com.chinasofti.shoot;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class ShootGame extends JPanel{
    public static final int WIDTH = 400;//窗口款
    public static final int HEIGHT = 654;//窗口高

    public static final int START = 0;//启动状态
    public static final int RUNNING = 1;//运行状态
    public static final int PAUS = 2; //暂停状态
    public static final int GAME_OVER = 3;//结束状态
    public  int state = 0;//当前状态 (默认启动状态)

    public static BufferedImage background;//背景图
    public static BufferedImage start;//启动图
    public static BufferedImage pause;//暂停图
    public static BufferedImage gameover;//游戏结束图
    public static BufferedImage airplane;//敌机图
    public static BufferedImage bee;//小蜜蜂图
    public static BufferedImage bullet;//子弹图
    public static BufferedImage hero0;//英雄机0
    public static BufferedImage hero1;//英雄机1

    static{
        try {
            background = ImageIO.read(ShootGame.class.getResourceAsStream("background.png"));
            start = ImageIO.read(ShootGame.class.getResourceAsStream("start.png"));
            pause = ImageIO.read(ShootGame.class.getResourceAsStream("pause.png"));
            gameover = ImageIO.read(ShootGame.class.getResourceAsStream("gameover.png"));
            airplane = ImageIO.read(ShootGame.class.getResourceAsStream("airplane.png"));
            bee = ImageIO.read(ShootGame.class.getResourceAsStream("bee.png"));
            bullet = ImageIO.read(ShootGame.class.getResourceAsStream("bullet.png"));
            hero0 = ImageIO.read(ShootGame.class.getResourceAsStream("hero0.png"));
            hero1 = ImageIO.read(ShootGame.class.getResourceAsStream("hero1.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Hero hero = new Hero();
    private FlyingObject[] flyings = {};
    private Bullet[] bullets = {};
//    ShootGame(){
//        flyings = new FlyingObject[2];
//        flyings[0] = new AirePlane();
//        flyings[1] = new Bee();
//        bullets = new Bullet[1];
//        bullets[0] = new Bullet(130,100);
//    }

    //----------------------------------
    public static FlyingObject nextOne(){//生产一个敌人
        Random rand = new Random();
        int type = rand.nextInt(20);//0-19
        if(type == 0){//返回小蜜蜂
            return new Bee();
        }else {//返回敌机
            return new AirePlane();
        }
    }
    int flyEnterIndex = 0;//敌人入场计数
    //敌人入场  按时间入场
    public void enterAction(){
        flyEnterIndex++;
        if(flyEnterIndex%1 == 0) {//每400毫秒运行一次

            FlyingObject obj = nextOne();
            //数组扩容
            flyings = Arrays.copyOf(flyings, flyings.length + 1);
            //将敌人对象赋值给数组
            flyings[flyings.length - 1] = obj;
        }
    }
    //子弹入场
    int shootIndex = 0;
    public void shootAction(){
        shootIndex++;
        if(shootIndex % 1 == 0) {
            Bullet[] bs = hero.shoot();
            bullets = Arrays.copyOf(bullets, bullets.length+bs.length);
            System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length);
        }
    }


    //走步的方法  hero（切图） 小蜜蜂  敌机  子弹
    public void stepAction(){
        hero.step();
        for(int i=0;i<flyings.length;i++){//遍历每一个敌人
            flyings[i].step();//敌人走一步
        }
        for (int i=0;i< bullets.length;i++){
            bullets[i].step();
        }
    }
    //删除越界飞行物
    public void outOfBoundAction(){
        /*
        我们能看到什么样的飞行物： 画框里的
        子弹数组  ，  敌人数组
        找到不越界的数组下标，将不越界的元素添加到可以显示的数组中；

         */
        //不越界敌人数组下标，不越界敌人的个数
        int index = 0;
        //声明不越界敌人数组
        FlyingObject[] flyingLives = new FlyingObject[flyings.length];
        for (int i=0;i<flyings.length;i++){
            FlyingObject f = flyings[i];//获取每一个敌人
            //若没越界
            if(!f.outOfBounds()){
                flyingLives[index] = f;//将不越界敌人添加到不越界敌人数组中
                index++;//下标增1，不越界敌人数量增1
            }
        }
        //将不越界敌人数组复制到flyings中，flyings元素个数为index
        flyings = Arrays.copyOf(flyingLives,index);
        //子弹
        index = 0;
        Bullet[] bulletLives = new Bullet[bullets.length];
        for (int i=0;i<bullets.length;i++){
            Bullet b = bullets[i];
            if(!b.outOfBounds()){
                bulletLives[index] = b;//将不越界子弹添加到不越界子弹数组中
                index++;//下标增1，不越界子弹数量增1
            }
        }
        bullets = Arrays.copyOf(bulletLives,index);
    }
    //游戏得分
    int score = 0;

    //所有子弹与所有敌人撞
    public void bangAction(){
        for (int i=0;i<bullets.length;i++){//遍历所有子弹
            Bullet b = bullets[i];//获取每一颗子弹
            bang(b);//一个子弹与所有敌人撞
        }
    }

    //一颗子弹与所有敌人碰撞
    public void bang(Bullet b){
        int index = -1;//被撞敌人下标, -1代表没撞上
        for(int i=0;i<flyings.length;i++){//遍历所有敌人
            FlyingObject f = flyings[i];//获取每一个敌人
            if(f.shootBy(b)){//如果被击中
                index = i;
                break;
            }
        }
        //撞上了
        if(index != -1){
            FlyingObject obj = flyings[index];//获取被撞敌人
            if(obj instanceof Enemy){//如果是敌人
                Enemy e = (Enemy)obj;//强转为敌人
                score += e.getScore();
            }
            if(obj instanceof Award){//如果是奖励
                Award a = (Award)obj;//强转为a
                int type = a.getType();//获取奖励类型
                switch (type){
                    case Award.DOUBLE_FIRE://若果是双倍火力
                        hero.addDoubleFire();//英雄机增加火力
                        break;
                    case Award.LIFE:
                        hero.addLife();//增加火力
                        break;
                }
            }
            //删除被撞敌人 将被撞敌机与数组最后一个元素交换
            FlyingObject temp = flyings[index];
            flyings[index] = flyings[flyings.length-1];
            flyings[flyings.length-1] = temp;
            //数组缩容，将最后一个元素删除
            flyings = Arrays.copyOf(flyings,flyings.length-1);
        }
    }

    //检查游戏结束
    public boolean isGameOver(){
        for (int i=0;i<flyings.length;i++){//遍历所有敌人
            FlyingObject f = flyings[i];//获取每一个敌人
            if(hero.hit(f)){//撞上了
                hero.subtractLife();//hero减少生命
                hero.setDoubleFire(0);//火力清零
                //删除被撞敌机
                FlyingObject temp = flyings[i];
                flyings[i] = flyings[flyings.length - 1];
                flyings[flyings.length - 1] = temp;
                //缩容
                flyings = Arrays.copyOf(flyings,flyings.length-1);
            }
        }
        return hero.getLife() <= 0;//当life小于等于0时游戏结束
    }

    //检查游戏结束action
    public void checkGrameOverAction(){
        if(isGameOver()){
            //System.out.println("游戏结束了哈哈！");
            state = GAME_OVER;//将游戏状态改变为GAME_OVER
        }
    }

    //执行启动
    public void action(){//定时器每10毫秒执行一次
        MouseAdapter l = new MouseAdapter() {//监听器对象
            //重写mouseMoved -- 鼠标移动事件
            @Override
            public void mouseMoved(MouseEvent e) {
                //super.mouseMoved(e);
                //System.out.println("我移动了x："+e.getX());
                int x = e.getX();
                int y = e.getY();
                hero.moveTo(x,y);
            }
            //重写鼠标点击事件
            @Override
            public void mouseClicked(MouseEvent e) {
                switch (state){//根据当前状态做不同操作
                    case  START: //启动状态时变成运行状态
                        state = RUNNING;
                        break;
                    case GAME_OVER://游戏结束便与你启动状态
                        //清场
                        score = 0;
                        hero = new Hero();
                        flyings = new FlyingObject[0];
                        bullets = new Bullet[0];
                        state = START;
                        break;

                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {//鼠标移入状态
                if(state == PAUS){//修改为运行状态
                    state = RUNNING;
                }
            }

            @Override
            public void mouseExited(MouseEvent e) {//鼠标移出游戏框
                if(state == RUNNING){//修改为暂停状态
                    state = PAUS;
                }
            }
        };



        this.addMouseListener(l);//处理鼠标操作事件
        this.addMouseMotionListener(l);//处理鼠标滑动事件

        Timer timer = new Timer();//定时器对象
        int intervel = 10;//时间间隔（以毫秒为单位）
        timer.schedule(new TimerTask() {
            @Override
            public void run() {//10毫秒运行一次
                if(state == RUNNING) {//运行状态执行
                    enterAction();//敌人入场
                    stepAction();//走步
                    shootAction();//子弹入场
                    outOfBoundAction();//删除越界飞行物
                    bangAction();
                    checkGrameOverAction();
                }
                repaint();//重画
            }
        }, 10, 10);
    }

    @Override
    public void paint(Graphics g) {
        g.drawImage(background,0,0,null);
        paintHero(g);//画英雄机对象
        paintFlyingObject(g);//画敌人
        paintBullets(g);//画子弹
        paintScore(g);//画分和命
        paintState(g);//画状态
    }
    //画状态
    public void paintState(Graphics g){
        switch (state){
            case START:
                g.drawImage(start,0,0,null);
                break;
            case PAUS:
                g.drawImage(pause,0,0,null);
                break;
            case GAME_OVER:
                g.drawImage(gameover,0,0,null);
                break;
        }

    }

    //画分和命
    public void paintScore(Graphics g){
        g.setColor(new Color(0xFF0000)); //设置成红色
        g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,24));
        g.drawString("SCORE:"+score,10,25);//画分
        g.drawString("LIFE:"+hero.getLife(),10,45);//画命
    }


    //画英雄机
    public void paintHero(Graphics g){
        g.drawImage(hero.image,hero.x,hero.y,null);
    }
    //画敌机和小蜜蜂
    public void paintFlyingObject(Graphics g){
        for (int i=0;i<flyings.length;i++){
            FlyingObject f = flyings[i];//获取每一个敌人
            g.drawImage(f.image,f.x,f.y,null);
        }
    }
    //画子弹
    public void paintBullets(Graphics g){
        for (int i=0;i<bullets.length;i++){
            Bullet b = bullets[i];//获取每一个子弹
            g.drawImage(b.image,b.x,b.y,null);//画每一个子弹
        }
    }


    public static void main(String[] args) {
        JFrame frame = new JFrame("Fly");//窗口
        ShootGame game = new ShootGame();//面板
        frame.add(game);//将面板添加到窗口中

        frame.setSize(WIDTH,HEIGHT);//设置窗口宽高
        frame.setAlwaysOnTop(true);//设置总在最上边
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置默认关闭窗口操作（窗口关系时退出程序）
        frame.setLocationRelativeTo(null);//设置窗口居中显示
        frame.setVisible(true);//设置窗口可见，尽快调用paint();

        game.action();
    }

}
